package triannon.client.sprites;

import java.awt.Graphics2D;
import java.awt.Point;

import triannon.client.sprites.renderer.Renderers;
import triannon.client.util.DebugUtil;
import triannon.client.util.TMath;

public class Unit extends LivingSprite {
	public Unit(String key, Fraction fraction) {
		this(key, fraction, 0, 0, 1d);
	}

	public Unit(String key, Fraction fraction, int x, int y) {
		this(key, fraction, x, y, 1d);
	}

	public Unit(String key, Fraction fraction, int x, int y, double health) {
		super(SpriteType.UNIT, key, fraction, x, y, health);
	}

	@Override
	public void update(long tpf) {
		super.update(tpf);

		if (actStep != null) {
			int destX = TMath.toWorldCoorninatesCenter(actStep.getX());
			int destY = TMath.toWorldCoorninatesCenter(actStep.getY());

			if (Point.distance(destX, destY, getCenterX(), getCenterY()) > 2) {
				if (path != null && path.getLength() > 0) {
					if (Point.distance(destX, destY, TMath.toWorldCoorninatesCenter(path
							.getStep(0).getX()), TMath.toWorldCoorninatesCenter(path.getStep(
							0).getY())) > Point.distance(getCenterX(), getCenterY(), TMath
							.toWorldCoorninatesCenter(path.getStep(0).getX()), TMath
							.toWorldCoorninatesCenter(path.getStep(0).getY()))) {

						actStep = path.removeFirstStep();
						destX = TMath.toWorldCoorninatesCenter(actStep.getX());
						destY = TMath.toWorldCoorninatesCenter(actStep.getY());
					}
				}

				int dirX = (int) Math.signum((destX) - getCenterX());
				int dirY = (int) Math.signum((destY) - getCenterY());

				setDirection(dirX, dirY);

				int oldX = getLevelX();
				int oldY = getLevelY();
				int newXWorld = x + (dirX * 4);
				int newYWorld = y + (dirY * 4);
				int newX = TMath.toLevelCoorninates(newXWorld);
				int newY = TMath.toLevelCoorninates(newYWorld);

				// this was just a test
				// if (field.blocked(this, newX, newY)) {
				// System.err.println("destination is blocked");
				// field.findPath(this, TMath.toLevelCoorninates(goToX), TMath
				// .toLevelCoorninates(goToY));
				// return;
				// }

				x = newXWorld;
				y = newYWorld;

				if (oldX != newX || oldY != newY) {
					System.err.println(newX + "," + newY);
					if (!field.moveSprite(oldX, oldY, newX, newY, getSpriteType()
							.getLayer())) {
						if (path != null) {
							actStep = path.removeFirstStep();
						}
						setLocation(getRect().x, getRect().y);
					}
				}

				updateRect();
			} else if (path != null) {
				actStep = path.removeFirstStep();
				if (actStep == null) {
					path = null;
				}
			}
		} else {
			goToX = -1;
			goToY = -1;
		}
	}

	private void setDirection(int dirX, int dirY) {
		AnimationKey animationKey = null;
		if (dirX > 0) {
			if (dirY > 0) {
				// move right down
				animationKey = AnimationKey.STAND_RIGHT_DOWN;
			} else if (dirY < 0) {
				// move right up
				animationKey = AnimationKey.STAND_RIGHT_UP;
			} else {
				// move right
				animationKey = AnimationKey.STAND_RIGHT;
			}
		} else if (dirX < 0) {
			if (dirY > 0) {
				// move left down
				animationKey = AnimationKey.STAND_LEFT_DOWN;
			} else if (dirY < 0) {
				// move left up
				animationKey = AnimationKey.STAND_LEFT_UP;
			} else {
				// move left
				animationKey = AnimationKey.STAND_LEFT;
			}
		} else {
			if (dirY > 0) {
				// move left down
				animationKey = AnimationKey.STAND_DOWN;
			} else if (dirY < 0) {
				// move left up
				animationKey = AnimationKey.STAND_UP;
			} else {
				// just stand still
			}
		}

		if (animationKey != null) {
			setAnimation(animationKey);
		}
	}

	@Override
	public void paint(Graphics2D g) {
		if (!alreadyPainted) {
			alreadyPainted = true;
			if (selected) {
				Renderers.getSelectionRenderer().paint(g, x, y, width, height);

				if (goToX >= 0 && goToY >= 0) {
					Renderers.getGoToRenderer().paint(g, getCenterX(), getCenterY(),
							goToX, goToY);
				}

				if (DebugUtil.getInstance().isRenderUnitPaths()) {
					Renderers.getPathRenderer().paint(g, actStep, path);
				}

			} else if (preSelected) {
				Renderers.getPreSelectionRenderer().paint(g, x, y, width, height);
			}

			renderer.paint(g, x - spriteInfo.getOriginX(), y
					- spriteInfo.getOriginY());

			if (selected || healthBarVisible) {
				Renderers.getHealthBarRenderer().paint(g, x, y, health, width, 5);
			}
		}
	}
}
